home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of the portable Forth environment written in ANSI C.
- * Copyright (C) 1995 Dirk Uwe Zoller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This file is version 0.9.13 of 17-July-95
- * Check for the latest version of this package via anonymous ftp at
- * roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
- * or sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
- * or ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
- *
- * Please direct any comments via internet to
- * duz@roxi.rz.fht-mannheim.de.
- * Thank You.
- */
- /*
- * filesub.c --- Subroutines for double number (64 Bit) arithmetics.
- * (duz 16Jul93)
- */
-
- #include "forth.h"
- #include "support.h"
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "nonansi.h"
- #include "missing.h"
-
- #if !defined HAVE_ACCESS
- int
- access (const char *fn, int how)
- {
- #if defined HAVE_STAT
-
- struct stat st; /* version using stat() */
-
- if (stat (fn, &st) != 0)
- return -1;
- switch (how)
- {
- default:
- return -1;
- case F_OK:
- return 0;
- case R_OK:
- return (st.st_mode & S_IREAD) ? 0 : -1;
- case W_OK:
- return (st.st_mode & S_IWRITE) ? 0 : -1;
- case X_OK:
- return (st.st_mode & S_IEXEC) ? 0 : -1;
- }
-
- #else
-
- FILE *f; /* limited version using ANSI-C fopen() */
-
- switch (how)
- {
- default:
- return -1;
- case F_OK:
- case R_OK:
- if ((f = fopen (fn, "r")) == NULL)
- return -1;
- fclose (f);
- return 0;
- case W_OK:
- if ((f = fopen (fn, "r+")) == NULL)
- return -1;
- fclose (f);
- return 0;
- case X_OK:
- return -1;
- }
-
- #endif
- }
- #endif
-
- long
- fsize (FILE * f) /* Result: file length, -1 on error */
- {
- #if defined HAVE_FSTAT && defined HAVE_FILENO
-
- struct stat st; /* version using fstat() */
- int fh = fileno (f);
-
- if (fh < 0 || fstat (fh, &st) < 0)
- return -1;
- return st.st_size;
-
- #else
-
- long pos, len; /* ANSI-C version using fseek()/ftell() */
-
- clearerr (f);
- pos = ftell (f);
- if (pos == -1)
- return -1;
- if (fseek (f, 0, SEEK_END) != 0)
- return -1;
- len = ftell (f);
- if (fseek (f, pos, SEEK_SET) != 0)
- return -1;
- return len;
-
- #endif
- }
-
- long
- size (const char *fn) /* Result: file length, -1 on error */
- {
- #if defined HAVE_STAT
-
- struct stat st;
-
- if (stat (fn, &st) != 0)
- return -1;
- return st.st_size;
-
- #else
-
- FILE *f;
- long len;
-
- f = fopen (fn, "r");
- if (f == NULL)
- return -1;
- len = fsize (f);
- fclose (f);
- return len;
-
- #endif
- }
-
- long
- copy (const char *src, const char *dst, long limit)
- /*
- * Copies file, but at most limit characters.
- * Returns destination file length if successful, -1 otherwise.
- */
- {
- FILE *f, *g;
- char buf[BUFSIZ];
- size_t n;
- long m;
-
- if ((f = fopen (src, "rb")) == NULL)
- return -1;
- if ((g = fopen (dst, "wb")) == NULL)
- {
- fclose (f);
- return -1;
- }
- for (m = limit; m; m -= n)
- {
- n = (size_t) (BUFSIZ < m ? BUFSIZ : m);
- n = fread (buf, 1, n, f);
- if (n == 0 || n != fwrite (buf, 1, n, g))
- break;
- }
- n = ferror (f) || ferror (g);
- fclose (f);
- fclose (g);
- return n ? -1 : limit - m;
- }
-
- int
- move (const char *src, const char *dst)
- /*
- * Renames or moves file, returns 0 on success, -1 on error.
- */
- {
- if (rename (src, dst) == 0)
- return 0;
- if (copy (src, dst, LONG_MAX) != -1)
- {
- return remove (src);
- }
- else
- {
- remove (dst);
- return -1;
- }
- }
-
- static int
- fextend (FILE * f, long size) /* make file longer */
- {
- long n;
-
- if (fseek (f, 0, SEEK_END) != 0)
- return -1;
- for (n = ftell (f); n < size; n++)
- if (putc (0, f) == EOF)
- return -1;
- return 0;
- }
-
- static int
- extend (const char *fn, long size)
- {
- FILE *f;
- int result;
-
- f = fopen (fn, "ab");
- if (f == NULL)
- return -1;
- result = fextend (f, size);
- fclose (f);
- return result;
- }
-
- #ifndef HAVE_TRUNCATE
- int
- truncate (const char *path, long length)
- {
- char tfn[L_tmpnam];
- long len;
-
- tmpnam (tfn);
- len = copy (path, tfn, length);
- if (len == length && remove (path) == 0)
- {
- return move (tfn, path);
- }
- else
- {
- remove (tfn);
- return 0;
- }
- }
- #endif
-
- int
- resize (const char *fn, long new_size)
- /*
- * Truncates or extends file.
- * Returns 0 if successful, -1 otherwise.
- */
- {
- long old_size;
-
- old_size = size (fn);
- if (old_size == -1)
- return -1;
- if (old_size <= new_size)
- return extend (fn, new_size);
- else
- return truncate (fn, new_size);
- }
-